package com.iwhalecloud.citybrain.flow.platform.manager.application.utils;

import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowReNodeAuthVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.form.TaskCandidateResultDto;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.model.NodeAuthVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.monitor.FlowTaskTraceVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowReNodeAuthRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowTaskService;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;

/**
　　* @description: 流程任务节点权限组件
　　* @author shenrm
　　* @date 2021/11/17 11:20
　　*/
@Component
@Slf4j
public class TaskNodeAuthComponent {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private FlowTaskService flowTaskService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private FlowReNodeAuthRepository flowReNodeAuthRepository;


    /**
     * 根据任务id和用户编码获取是否节点权限
     *
     * @param taskId
     * @param userCode
     * @return
     */
    public NodeAuthVo getNodeAuthByTaskIdAndUserCode(String taskId, String userCode) {
        FlowTaskTraceVo flowTaskTraceVo = flowTaskService.getFlowTaskByTaskIdOrUserCode(taskId,userCode);
        if (Objects.nonNull(flowTaskTraceVo)){
            TaskCandidateResultDto taskCandidateResultDto = new TaskCandidateResultDto();
            taskCandidateResultDto.setTaskId(flowTaskTraceVo.getTaskId());
            taskCandidateResultDto.setTaskStatus(flowTaskTraceVo.getLinkStatus());
            taskCandidateResultDto.setStatus(flowTaskTraceVo.getStatus());
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(flowTaskTraceVo.getProcessInstanceId()).singleResult();
            List<FlowReNodeAuthVo> flowReNodeAuthVoList = flowReNodeAuthRepository.listNodeAuthByProcdefIdAndNodeCode(processInstance.getProcessDefinitionId(),flowTaskTraceVo.getActivityId());
            if (Objects.nonNull(flowReNodeAuthVoList) && !flowReNodeAuthVoList.isEmpty()){
                NodeAuthVo nodeAuthVo = new NodeAuthVo();
                for (FlowReNodeAuthVo flowReNodeAuthVo : flowReNodeAuthVoList) {
                    try {
                        Field field = nodeAuthVo.getClass().getDeclaredField(flowReNodeAuthVo.getAuthName());
                        field.setAccessible(true);
                        field.set(nodeAuthVo,flowReNodeAuthVo.getAuthSwitch());
                    } catch (NoSuchFieldException e) {
                        log.error("get field error,continue");
                    } catch (IllegalAccessException e) {
                        log.error("set field value error,continue");
                    }
                }
                return nodeAuthVo;
            }
        }
        return null;
    }
}
